/**
 * 
 */
package com.netscenery.yang.model;

import org.jdom2.Attribute;
import org.jdom2.Element;

import com.netscenery.util.ErrTag;
import com.netscenery.util.QName;
import com.netscenery.util.XMLTag;
import com.netscenery.yang.YangKeyword;
import com.netscenery.yang.YangStatement;
import com.netscenery.yang.abnf.Parser;
import com.netscenery.yang.abnf.ParserException;
import com.netscenery.yang.abnf.Rule;
import com.netscenery.yang.parser.YangParserException;

/**
 * @author llly
 *
 */
public class IdentityRef extends Type {
	private String baseIdentity;

	/**
	 * 
	 */
	public IdentityRef() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param env
	 * @param base
	 */
	public IdentityRef(Env env, BuiltinType base) {
		super(env, base);
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param env
	 * @param base
	 * @param name
	 */
	public IdentityRef(Env env, BuiltinType base, String name) {
		super(env, base, name);
		// TODO Auto-generated constructor stub
	}

	/**
	 * @return the base
	 */
	public String getBaseIdentity() {
		return baseIdentity;
	}

	/**
	 * @param base the base to set
	 */
	public void setBaseIdentity(String base) {

		this.baseIdentity = base;
	}
	

	
	public boolean checkIdentity(String identity){
		if (null == identity){
			return false;
		}
		if (!ModelElement.isNodeIdentifier(env,identity)){
			return false;
		}
		Module module = env.getCurModule();
		if (null == module){
			return false;
		}
		boolean isLocal = true;
		String prefix= null;
		QName qname = new QName(identity);
		if (qname.isQName()){
			if (!qname.getPrefix().equals(module.getPrefix())){
				isLocal = false;
				prefix = qname.getPrefix();
			}			
		}
		
		if (isLocal){
			if (null == module.getIdentity(identity)){
				return false;
			}
		}
		else {
			Module refModule = module.getModule(prefix);
			if (null == refModule){
				return false;
			}
			
			if (null == refModule.getIdentity(qname.getLocalName())){
				return false;
			}
		}
		
		
		
		return true;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#validate()
	 */
	@Override
	public Validator validate() {
		Validator validator = new Validator();
		if (null == getBaseIdentity()){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,"base identity must be present."));
		}
		else {
			if (!checkIdentity(this.getBaseIdentity())){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,"invalid base identity."));

			}
		}
		
		Validator sValidator = super.validate();
		validator.copy(sValidator);
		return validator;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#toYang()
	 */
	@Override
	public YangStatement toYang() {
		YangStatement identityref = new YangStatement(YangStatement.YANG_STATEMENT_TYPE,this.name);
		if (null != this.getBaseIdentity()){
			YangStatement baseStatement = new YangStatement(YangStatement.YANG_STATEMENT_BASE,this.getBaseIdentity());
			identityref.addChild(baseStatement);
		}
		return identityref;
		
	}
	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#toYang()
	 */
	@Override
	public Element toYin() {
		Element leafref = new Element(YangStatement.YANG_STATEMENT_TYPE,env.getNs());
		Attribute name = new Attribute(XMLTag.XML_TAG_NAME,this.name);
		leafref.setAttribute(name);
		if (null != getBaseIdentity()){
			Element baseElement = new Element(YangStatement.YANG_STATEMENT_BASE,env.getNs());
			Attribute value = new Attribute(XMLTag.XML_TAG_NAME,this.getBaseIdentity());
			baseElement.setAttribute(value);
			leafref.addContent(baseElement);
		}
		return leafref;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#toXML()
	 */
	@Override
	public Element toXML() {
		
		return null;
	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#readXML(org.jdom2.Element)
	 */
	@Override
	public int readXML(Element element) throws ModelException {
		if (null == element){
			return MODELELEMENT_OK;
		}
	
	
		

		return MODELELEMENT_OK;

	}

	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#readYANG(com.netscenery.modeldesigner.util.YangStatement)
	 */
	@Override
	public int readYANG(YangStatement statement) throws YangParserException {
		if (null == statement){
			return MODELELEMENT_OK;
		}
		if (statement.getKeyword().equals(YangStatement.YANG_STATEMENT_BASE)){
			this.setBaseIdentity(statement.getArgument());
		}
		else {
			return MODELELEMENT_FAIL;
		}
		

		return MODELELEMENT_OK;
	}
	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Type#readYANG(com.netscenery.modeldesigner.util.YangStatement)
	 */
	@Override
	public int readYin(Element statement) throws ModelException {
		if (null == statement){
			return MODELELEMENT_OK;
		}
		if (statement.getName().equals(YangStatement.YANG_STATEMENT_PATH)){
			String base = statement.getAttributeValue(XMLTag.XML_TAG_NAME);
			this.setBaseIdentity(base);
		}
		else {
			return MODELELEMENT_FAIL;
		}
		

		return MODELELEMENT_OK;
	}

	
}
